package com.jt.common.util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.text.StrTokenizer;


public class IpUtil {

  /**
   * 获取用户真实IP地址，不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址, 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值，究竟哪个才是真正的用户端的真实IP呢？
   * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。 如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130,
   * 192.168.1.100 用户真实IP为： 192.168.1.110
   *
   * @param request
   * @return
   */
  public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
  public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$");

  public static String longToIpV4(long longIp) {
    int octet3 = (int) ((longIp >> 24) % 256);
    int octet2 = (int) ((longIp >> 16) % 256);
    int octet1 = (int) ((longIp >> 8) % 256);
    int octet0 = (int) ((longIp) % 256);
    return octet3 + "." + octet2 + "." + octet1 + "." + octet0;
  }

  public static long ipV4ToLong(String ip) {
    String[] octets = ip.split("\\.");
    return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16) + (
        Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]);
  }

  public static boolean isIPv4Private(String ip) {
    long longIp = ipV4ToLong(ip);
    return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255"))
        || (longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255"))
        || longIp >= ipV4ToLong("192.168.0.0")
        && longIp <= ipV4ToLong("192.168.255.255");
  }

  public static boolean isIPv4Valid(String ip) {
    return pattern.matcher(ip).matches();
  }

  public static String getIpAddress(HttpServletRequest request) {
    String ip;
    boolean found = false;
    if ((ip = request.getHeader("x-forwarded-for")) != null) {
      StrTokenizer tokenizer = new StrTokenizer(ip, ",");
      while (tokenizer.hasNext()) {
        ip = tokenizer.nextToken().trim();
        if (isIPv4Valid(ip) && !isIPv4Private(ip)) {
          found = true;
          break;
        }
      }
    }
    if (!found) {
      ip = request.getRemoteAddr();
    }
    return ip;
  }

  public static String getLocalIpAddress() {
    String ip = null;
    try {
      ip = InetAddress.getLocalHost().getHostAddress();
    } catch (UnknownHostException e) {

    }
    return ip;
  }
}
